天天看點

oracle rac中讓sql語句在指定的節點執行的方法

oracle rac中讓sql語句在指定的節點執行的方法

原創 Linux作業系統 作者:eric0435 時間:2013-09-05 13:51:30 8660 0

rac中一條查詢語句并行到各個節點執行沒完成被中斷後被限制到特定節點上執行時查詢時查詢語句執行不了.

客戶情況是四個節點的11g rac,五個險種在做資料轉換,由于一個險種的有些資料轉換腳本的查詢使用了并行執行被并行到别的節點上,而其它險種發現後将并行程序kill了.後面該險種的被kill掉的查詢語句在特定節點上執行時當查詢特定月份的資料時會卡住.産生的等待事件是gc cr request.

global cache cr request

當一個程序通路需要一個或者多個塊時,它會首先檢查自己的CACHE是否存在該塊,如果發現沒有,就會先通過global cache賦予這些塊共享通路的權限,然後再通路。假如,通過global cache 發現這些塊已經在另一個執行個體的CACHE裡面,那麼這些塊就會通過CACHE FUSION,在節點之間直接傳遞,同時出現global cache cr request等待事件

注意:在10G以後,global cache cr request 已經簡稱為 gc cr request

查詢語句如下:

            SELECT /*+ INDEX(MBF,IDX_MT_BIZ_FIN_DATE)USE_NL(MBF,MFF) */

                   mff.hospital_id AKB020,    --醫療機構編号

                   mff.serial_no AAZ218,    --業務序列号

                   mff.serial_fee AAZ213,    --費用序列号

                   mff.stat_type AKA063,    --統計類别

                   mff.fee_batch PKA001,    --費用批次

                   decode(mff.medi_item_type,0,'2',1,'1',2,'4',3,'5') AKE003,    --項目藥品類型(0:項目,1:西藥,2:中成藥,3:中草藥)

                   mff.item_code AKE001,    --中心藥品項目編碼

                   mff.item_name AKE002,    --中心藥品項目名稱

                   mff.his_item_code AKE005,    --醫院藥品項目編碼

                   mff.his_item_name AKE006,    --醫院藥品項目名稱

                   mff.serial_apply AAZ267,    --申請序列号

                   mff.fee_date PKA051,    --費用發生時間

                   mff.model PKA052,    --劑型

                   mff.factory PKA053,    --廠家

                   mff.standard PKA054,    --規格

                   mff.unit PKA055,    --計量機關

                   mff.price PKA056,    --單價

                   mff.dosage PKA057,    --用量

                   mff.money PKA058,    --金額

                   mff.reduce_money PKA059,    --沖減金額(主要為計算友善使用)

                   mff.usage_flag PKA060,    --使用标志(1:出院帶藥 2:搶救用藥 3:急診)

                   mff.usage_days PKA061,    --出院帶藥天數

                   mff.opp_serial_fee PKA062,    --對應費用序列号

                   mff.input_staff PKA063,    --錄入人工号

                   mff.input_man PKA064,    --錄入人

                   mff.input_date PKA065,    --錄入時間

                   mff.calc_flag PKA066,    --計算标志

                   mff.frozen_flag PKA067,    --費用當機标志,用來表識參保人所在機關的基本醫療保險被當機期間錄入的費用。0:未當機;1:已當機;2:當機已處理

                   mff.frozen_serial_fee PKA068,    --對應當機的費用序列号

                   mff.trans_date PKA069,    --費用上傳時間

                   mff.recipe_no PKA070,    --處方号

                   mff.hos_serial PKA071,    --對應醫院費用号

                   mff.recipe_hospital_id PKA072,    --處方醫院編号

                   mff.recipe_hospital_name PKA073,    --處方醫院名稱

                   mff.doctor_no PKA074,    --處方醫生編号

                   mff.doctor_name PKA075,    --處方醫生姓名

                   mff.audit_flag PKA076,    --稽核标志

                   mff.trans_flag PKA044,    --傳輸标志(0:未傳輸 1:已成功傳輸 2:未成功傳輸)

                   mff.valid_flag AAE100  --有效标志

              FROM gzyb.mt_biz_fin/*@gzybcx_link*/ mbf,

                   gzyb.mt_fee_fin/*@gzybcx_link*/ mff

             WHERE mbf.hospital_id = '004003'

               AND mbf.fin_date >= to_date('20130101', 'yyyy-mm-dd')

               AND mbf.fin_date  < to_date('20130201', 'yyyy-mm-dd')

               AND mbf.valid_flag = '1'

               AND mbf.hospital_id = mff.hospital_id

               AND mbf.serial_no = mff.serial_no;

在指定的特定節點執行上面的語句會産生gc cr request,因為之前被分發到别的節點上執行,該查詢的部分資料被緩存到其它的節點上了.而現在不能并行在指定了特定執行個體來運作上面的查詢,是以查詢不能通路其它節點執行個體的sga,因為我的機器名是JINGYONG.從下面的查詢可以看到上面的語句在沒加parallel提示時該語句是在特定節點prddb02執行的.

      SID    SERIAL# USERNAME       PROGRAM                  MACHINE

---------- ---------- -------------  -----------------------  ------------------------

      6345       1387 SICP3_GZYB     oracle@prddb02 (J001)    prddb02

      6454        371 SICP3_GZYB     oracle@prddb02           WORKGROUP\POWERSI-HP

      2508       1513 SICP3_GZYB     oracle@prddb02 (J000)    prddb02

      7865       234  SICP3_GZYB     oracle@prddb02 (J002)    WORKGROUP\JINGYONG

sid=7865,serial#=234就上面執行的sql語句.

當給上面的sql語句加上并行parallel提示

            SELECT /*+ INDEX(MBF,IDX_MT_BIZ_FIN_DATE)USE_NL(MBF,MFF) parallel(mff,1) */

這時查詢雖然指定了運作的特定執行個體還是被并行到其它節點上執行了進而能通路其它執行個體sga是以查詢很快就能查詢出來

從下面的查詢可以看到當加并行parallel後上面的sql雖然是在特定執行個體執行但卻被并行到其它節點執行了

SID SERIAL# USERNAME PROGRAM MACHINE

---------- ---------- ------------- ----------------------- ------------------------

6345 1387 SICP3_GZYB oracle@prddb02 (J001) prddb02

6454 371 SICP3_GZYB oracle@prddb02 WORKGROUP\POWERSI-HP

2508 1513 SICP3_GZYB oracle@prddb02 (J000) prddb02

是以上面的sql在特定執行個體執行卡住的原因找到了.

要想讓并行程序隻在單節點上執行可以設定parallel_force_local參數為true

SQL> show parameter force

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

parallel_force_local                 boolean     TRUE

如果想要讓job也在指定的節點上運作而不被并行到其它節點上執行在建立job時要指定instance參數,将instance參數指定為你要使用的節點