I am going to use the CDC on two tables that hold planning dimension information; one table has the parent/child/alias details and a primary key of ID.

The second table holds the member properties.

The referential integrity is set on the ID column meaning a record cannot be inserted into the table unless the ID exists in the member’s table.
The idea of today’s example is that I am going to capture updates to these tables and then update planning with the changes, the principle of using consistent journalizing is pretty much the same as using simple so I will assume that you have read part 1 so I don’t have to repeat too much.
A new model was created and the above two tables reversed.

This time the consistent set option was chosen under the Journalizing tab

Next step was to add both the tables to use CDC, right click over the datastore and select.

Now when using a group of datastores you have to make sure that the order of the tables is set up correctly, for instance in my example the members table must be before the properties table to preserve the referential integrity.

If you click on the organize tables icon in the journalized tables tab it will set up the order by basing it on the tables foreign keys.

The subscriber can now be created just like when working with simple journalizing.
Once this is applied a session runs to create the subscriber database table, also four extra tables are created these tables are not created when using simple journalizing.
SNP_CDC_SUBS

SNP_CDC_SET

The other two tables created are SNP_CDC_SET_NAME & SNP_CDC_OBJECT, these tables are not populated until the journal is started.
Now the journal can be started by right clicking the model > Changed Data Capture > Start Journal
The session creates the tables, views and triggers required for journalizing.
The table SNP_CDC_OBJECT holds the information about what has been created.

As you can see triggers are created on the two tables that are going to be monitored for changes (HIER_MEMBERS and HIER_PROPERTIES)
Tables are created which will hold the information about the changes (J$HIER_MEMBERS & J$HIERPROPERTIES)

The window_id field relates to the information stored in the SNP_CDC_SET table, the ID field relates to the ID in the monitored table.
When a change happens to the monitored tables, the trigger is fired and this table will be populated with the ID of the record.
Views are also created which will display any changes that have occurred.
The process of how the changes are tracked in the database tables is a lot more complicated and involved than when using simple journalizing, I am not going to go into the depths of that detail and concentrate more on how to set the process in ODI.
The next stage is to set up the interface that will load the changes into planning, the two datastores are dragged onto the source, and the join between the two tables is automatically created. Just like with simple journalizing you need to tick the “Journalized data only box” which creates three extra journal fields to the datastore (JRN_SUBSCRIBER, JRN_FLAG, JRN_DATE)

The automatically generated filter needs updating to change the name of the subscriber to the one you are using.

I also added to the filter so only inserts/updates to the table are retrieved; the rest of the interface is set up just like you would for any of loading metadata to planning.
After inserting a record into the monitored datastores you can view the changes from ODI using “Changed Data Capture” > Consumption > “Extend Window”

This will execute a session that computes all the changes to the datastores.

Selecting to display the data uses the SQL view to retrieve any records where updates have occurred.

Executing the interface will load any updates straight to planning, to reset the journal capturing after you have run the interface can be achieved by using “Changed Data Capture” > Consumption > “Purge Journal”
This is fine but you need to be able automate using the “Extend Window” and Purge functionality; this can be performed in a package.
Before I move on to the package I duplicated the interface and removed the properties table, updated the filter to retrieve records where the flag = ‘D’ which means it would retrieve journalized records that have been deleted, on the target I added ‘Delete Level 0’ to the operation column. This interface will now remove any members from planning where they have been removed from the journalized datastore.

Right, on to the package, the first step is just like I showed in Part 1 by using the ODI tool “OdiWaitForLogData”
The only difference being that with consistent set journalizing you can’t use the “Table Name” parameter and have to use the CDC Set parameter.

In the CDC Set parameter it needs to be the name of your logical schema and model name, this can be retrieved by using an ODI API function, the code needs to be set as :-
<%=odiRef.getObjectName("L","model_code","logical_schema", "D")%>
In my example the logical schema is called CDC_PLANNING and the model CDC_Planning so the API function required to be updated to :-

Now to perform the equivalent function of “Extend Window”, drag the model onto the diagram and set the type to “Journalizing Model” and check the “Extend Window” box.

The two interfaces that load any updates and remove members are dragged onto the diagram.

Now that the planning loads have been run we need to reset the journalizing by using the purge command, this can be done like before by dragging the model on to the diagram but this time making sure the “Purge Window” box is checked.

I thought this would be the end of the story but when the purge was run it didn’t reset the journal so the details were still held in the journal tables (J$HIER_MEMBERS & J$HIER_PROPERTIES) which meant if I ran the process again it would load the same records again.
I will try and explain why this is happening and how to overcome it, if you are not interested in the techie bits then I would skip this section in case you fall asleep.
When you run the command “Purge Journal” it carries out the following steps.

So say in my example I had the values CUR_WINDOW_ID = -1, CUR_WINDOW_ID_DEL= -1, CUR_WINDOW_ID_INS = -1
The table would now hold

The next stage is that it updates the journal tables with the value from CUR_WINDOW_ID_INS

So if you have updated any records then they will exist in the journal table and will be tagged with the value in CUR_WINDOW_ID_INS

I had already inserted a record into the table I was monitoring so the window_id column was updated.
It repeats this process for each journal table and follows a similar process for any deletions but uses the value from CUR_WINDOW_DEL
Ok, so what happens when a purge is run; well the following SQL is run for each journal table.

This time it is deleting any values in the journal table where the window_id value is less than or equal to minimum value in the min_window_id column of the SNP_CDC_SUBS table.

So the logic is delete anything in the journal table where the window_id is less than or equal to -1, this means nothing will be deleted so the purge in this circumstance is doing nothing.
This is where the CDC functions Lock Subscriber and Unlock Subscriber come into play.
If you run the Lock Subscriber function and select the subscriber it carries out the following.

The question mark relates to the subscriber that was chosen, it runs some jython code that populates the question mark with subscriber info.
It is updating the SNP_CDC_SUBS table with values from the SNP_CDC_SET table, so after it has completed the SNP_CDC_SUBS table in my example looks like :-

Running the purge now would still not result in any records being deleted because the MIN_WINDOW_ID value has not changed.
So finally lets see what happens when the Unlock Subscriber function is run.

This updates the SNP_CDC_SUBS table and sets the MIN_WINDOW_ID value to the value of MAX_WINDOW_ID_INS which results in

So now there is a value of 0 in the MIN_WINDOW_ID column and running the purge will this time delete records from the journal table

In the journal table the WINDOW_ID column is 0 and the purge command logic will delete anything which is less than or equal to the MIN_WINDOW_ID value (0)
This is what the documentation has to say about “Lock Subscribers”
Although the extend window is applied to the entire consistency set,
subscribers consume the changes separately. This operation performs a subscriber(s) specific
"snapshot" of the changes in the consistency window. This snapshot includes all the changes
within the consistency window that have not been consumed yet by the subscriber(s). This
operation is implemented using a package step with the Journalizing Model Type. It should
be always performed before the first interface using changes captured for the subscriber(s).
Basically if you want to capture changes to the subscriber you must use this function to be able to capture correctly or you will end up like I did the first time I tried to purge the journal.
I thought I would cover what happens in case the same thing happens to you.
Back to the package, I updated “Capture_Changes” to include “Lock Subscribers” for the subscriber I was using

I updated “Reset_Journalizing” to include the “Unlock Subscribers” function and added the subscriber.

Finally I generated a scenario and added the OdiStartScen utility to the diagram, this executes the scenario again which is a much more cleaner and sensible way than just looping back to the first step, if you loop straight back it can cause problems such as the logs growing out of control. I regenerated the scenario so it took into account the last step.

Once the scenario is executed it will wait until 2 records have been updated and then run the journalizing process that captures the records, then the interfaces are run to load metadata into planning, finally the journals are purged and the process will be started again.
I know that I could of created just once interface to handle both the updates and deletes to planning by using the inbuilt functions to change the operation parameter but I just wanted to highlight what could be achieved if you wanted to split loads out.
Well that’s me done for today, time for a bit of a break I think.

10 comments:
John,
Thank You for sharing your Knowledge.
John
At the end of the package, if you loop back to the start, you may end up with a task running which for which you can't purge the log. One way round this is to generate a scenario from the package, and make the last step an OdiStartscen of the scenario. This will make each execution of the data movement granular, so that the log can be archived or purged, rather than just growing. I have seen circumstances where customers have done that, and ended up blowing their tablespaces on the log schema, causing all sort of problems.
Thanks.
Craig
Thanks for the useful comments Craig, I have updated the blog so it uses OdiStartScen instead of the quick and dirty way of looping straight back to the first step.
Cheers
John
Hi John,
Question on...do we really need CDC? For building metadata for Hyperion application?
Alternative, if we do a total rebuild of the outline dimension (Ex: Acct)wouldn't that be simple?
I'm not 100% sure, but i heard that ODI is smart enough not to touch members property if nothing changed for that particular member in the source if a total build is performed. And if change is seen for the member, only that specific change is applied...keeping the planning UDA's, Formulas, Storage option..etc same as earlier.
Step:1
- Data source: table (DW) with parent-child relation
- Target: planning
-- Load Parent members first into Planning to make sure parent exits
-- Load the full table file with Parent-child relationship to load all members
Appreciate your feedback.
Thank you.
素食餐廳 交友 婚友 婚友社 婚友聯誼 愛情公寓 相親 相親銀行 聯誼 命理網 姓名學Hook and Loop 婚禮佈置 情人花束 新竹花店婚友聯誼社 愛情會場佈置 氣球佈置二手車健檢 醫學美容 淨膚雷射 汽車美容 法拍屋 水餃 清潔公司 塑膠袋批發 塑膠袋工廠 實驗動物 到府坐月子 坐月子 坐月子中心 坐月子餐 孕婦 月子餐 到府坐月子 中古車 今日金價 坐月子中心 坐月子中心台中 坐月子中心台北 台北人力銀行
金價查詢 月子餐 月子中心 坐月子餐 月子餐外送 月子餐食譜 統一發票9 10月 金價 統一發票9 10月 找工作 統一發票7 8月 求職 1111求職人力銀行 104求職人力銀行 104人力銀行 統一發票5 6月 104人力銀行 104求職人力銀行 塑膠袋 統一發票1 2月 金價 黃金價格 金價查詢 黃金買賣 環保袋 肉毒桿菌 黃金 統一發票3 4月 坐月子 sum中古車 1111人力銀行 104求職人力銀行 1111人力銀行求職 黃金價格查詢 中古車買賣 塑膠袋 統一發票9 10月 塑膠袋批發 中古車 中古車買賣消防公司 地板施工 網路廣告 網路行銷
網路行銷食品批發 拉麵 T恤 慈善 店面租賃 店面出租 店面出售 花茶 花草茶 肝癌 健康檢查 身體檢查 飛梭雷射 雷射溶脂 直航機票 養生茶 招牌 led招牌 招牌製作 美國月子中心 保養 美國月子中心 美國月子中心 團體服 OBU 投審會 會計師事務所 會計師 工商登記 彌月蛋糕 公司登記 保時捷 法拉利 福利 <包子 肉粽 宅配美食 四神湯 搬家公司 訂房網花東旅遊 桃園土地 桃園房屋仲介 桃園房屋 桃園房屋網 桃園房屋買賣
馬桶 馬桶不通 國外旅遊 國外機票 團體旅遊 直航機票 簽證熱水器 蘭花 化糞池 抽化糞池 便宜機票 國內旅遊 抽水肥 太陽能 水管不通 洗水塔 消毒 通水管 通馬桶 馬桶 馬桶不通 上順旅行社 五福旅行社 大興旅行社 天喜旅行社 天福旅行社 日本旅行社 日本旅遊 日本機票 日本自由行 日本訂房 包通 抽化糞池 抽水肥 水管不通 洗水塔 自由行 訂房 雄獅旅遊 汽車美容 汽車美容 三久太陽能黃金價格查詢 貸款 信用貸款
漆彈 搬家公司 會場設計紙盒訂裝 展覽設計展場設計 展覽設計 消防設備 消防設備 機電 崴立機電 牙齒美白 植牙 牙周病治療方法 植牙費用 牙周病 光纖美白除毛 肉毒桿菌除皺 紙盒印刷 紙袋包裝 當鋪 當舖 借錢 手提紙袋 紙袋工廠 包裝紙袋 手提袋 包裝盒 股票教學 股市分析 股市億萬贏家 股票軟體 股票行情 ferrari 賣車 賓士 lexus紙袋印刷 會場設計 貸款 票貼 二胎 包裝紙盒融資 工商融資 支票貼現 借款 微晶瓷 3D飛梭雷射 淨膚雷射 汽車借款 汽車貸款 徵信 徵信社 外遇 彌月送禮 喜餅
彌月 離婚 獸醫院 寵物住宿 白內障 心絲蟲 腎衰竭 狗皮膚病RF PCB Rigid-Flex PCB 動物醫院 洗鞋店 加盟 洗鞋 洗包包 洗鞋加盟 酒店式公寓旅行社slot machine manufacturer 杭州旅遊北京自由行上海自由行旅遊網律師
台北民宿 房屋仲介 法拍屋 法拍 法拍屋查詢系統板橋法拍屋 大台北法拍屋 原裝進口燈飾 流行燈飾 3D立體印刷 印刷服務回收 燈 照明 彩盒 回收電腦 水晶燈 日租套房 台北日租 apartment 太平山民宿 宜蘭民宿推薦 法律事務所
Post a Comment