安裝PSU後一定要執行catbundle.sql psu apply指令碼嗎

strivechao發表於2019-04-19

一服務公司來單位生產庫巡檢,檢查結果為資料庫軟體安裝了PSU補丁,但是資料庫中沒有執行相關的升級指令碼,並且提交了相關的書面報告給單位建議在資料庫中執行catbundle.sql psu apply指令碼。

真的像服務公司說的那樣嗎,看了看報告,原來服務公司是根據查詢registry$history表中的記錄來檢查的,自己查詢了一下,確實一條記錄都沒有,然後又回去仔細看了一遍PSU的readme,如果採用custome方式建庫的話是不需要執行catbundle.sql的呀,當然都是紙上談兵,還是動手分析一下catbundle.sql psu apply做了哪些動作吧。

首先分析一下catbundle.sql指令碼,其中有段這樣的話:
catbundle.sql will look in $ORACLE_HOME/rdbms/admin for an input XML
file named bundledata_ .xml (i.e. bundledata_CPU.xml)
for information about which patches in the bundle contain which SQL
files.

即根據$ORACLE_HOME/rdbms/admin/bundledata_PSU.xml檔案中的內容來決定該PSU中需要執行哪些SQL檔案,bundledata_PSU.xml檔案中的部分內容:

?/rdbms/admin/prvtjob.plb
?/rdbms/admin/dbmsaqds.plb
?/rdbms/admin/prvtaqds.plb
?/rdbms/admin/prvtlmd.plb
?/rdbms/admin/prvtlmc.plb
?/rdbms/admin/prvtbpp.plb
?/rdbms/admin/prvtlsby.plb
?/rdbms/admin/dbmssum.sql
?/rdbms/admin/prvtsum.plb
?/rdbms/admin/prvtsms.plb
?/rdbms/admin/prvtdefr.plb
?/rdbms/admin/prvtbstr.plb
?/rdbms/admin/prvtbcap.plb


?/rdbms/admin/initqsma.sql


應該是根據資料庫安裝不同的元件需要執行不同的SQL,繼續分析catbundle.sql指令碼,檔案的最後有如下幾行:
COLUMN script_file NEW_VALUE sf NOPRINT;
SELECT :scriptFile AS script_file FROM dual;
@&sf
即script_file為需要執行的指令碼,將catbundle.sql複製一份,最後幾行內容修改為:
BEGIN
DBMS_OUTPUT.PUT_LINE('script. file: ' || :scriptFile);
END;
看看打出來需要執行的指令碼叫什麼。
SQL>@catbundle_test.sql psu applay
輸出script. file: /u01/app/oracle/product/10.2.0/db_1/rdbms/admin/catbundle_PSU_OTEST_APPLY.sql

原來執行的SQL檔案是catbundle_PSU_OTEST_APPLY.sql,檢視該檔案內容,如下內容和bundledata_PSU.xml檔案中的內容相符合:
PROMPT Processing Oracle Database Packages and Types...
ALTER SESSION SET current_schema = sys;
@?/rdbms/admin/prvtjob.plb
@?/rdbms/admin/dbmsaqds.plb
@?/rdbms/admin/prvtaqds.plb
@?/rdbms/admin/prvtlmd.plb
@?/rdbms/admin/prvtlmc.plb
@?/rdbms/admin/prvtbpp.plb
@?/rdbms/admin/prvtlsby.plb
@?/rdbms/admin/dbmssum.sql
@?/rdbms/admin/prvtsum.plb
@?/rdbms/admin/prvtsms.plb
@?/rdbms/admin/prvtdefr.plb
@?/rdbms/admin/prvtbstr.plb
@?/rdbms/admin/prvtbcap.plb
@?/rdbms/admin/prvtaqiu.plb
PROMPT Processing Oracle Java Supplied Packages...
ALTER SESSION SET current_schema = sys;
@?/rdbms/admin/initqsma.sql
@?/rdbms/admin/initcdc.sql

即根據資料庫安裝的元件,需要執行上述SQL指令碼,這裡只有CATPROC和CATJAVA元件,之後執行完後往registry$history表中插入記錄:
PROMPT Updating registry...
INSERT INTO registry$history
(action_time, action,
namespace, version, id,
bundle_series, comments)
VALUES
(SYSTIMESTAMP, 'APPLY',
SYS_CONTEXT('REGISTRY$CTX','NAMESPACE'),
'10.2.0.2',
2,
'PSU',
'PSU 10.2.0.4.2');
COMMIT;

這裡就重點分析那些plb檔案在使用custome方式建庫的時候是否呼叫了,為此寫了一個SHELL指令碼:
mygrep() 
{
fn=$1 #儲存傳入的檔名
shift
msg=$* #儲存傳入的訊息
fnt=`echo $fn | cut -d . -f 1` #由於SQL檔案中有的是寫成@@dbmssum模式,有的是寫成@@prvtjob.plb模式,
ff=`grep "@@$fn" *.sql || grep "@@$fnt" *.sql` #即帶副檔名和不帶副檔名,因此可能需要截斷一下
if [ "$ff" != "" ]; then #對於catjava.sql中的呼叫是不帶@@的,所以可以進入到下面迴圈的是catproc.sql的
fn1=`echo $ff | awk -F:@@ '{print $1}'` 
if [ "$fn1" = "catproc.sql" ]; then
if [ "$msg" = "" ]; then
echo "$fn found in $fn1"
else
echo "$msg$fn found in $fn1"
fi
else
msg="$msg$fn found in $fn1 \t"
mygrep $fn1 $msg
fi
else
grep -q $fn catjava.sql
if [ "$?" = "0" ]; then
echo "$fn found in catjava.sql"
else
echo "$fn not found"
fi
fi
}


for f in `cat << EOF #需要查詢的SQL檔名
prvtjob.plb
dbmsaqds.plb
prvtaqds.plb
prvtlmd.plb
prvtlmc.plb
prvtbpp.plb
prvtlsby.plb
prvtsum.plb
prvtsms.plb
dbmssum.sql
prvtdefr.plb
prvtbstr.plb
prvtbcap.plb
prvtaqiu.plb
initqsma.sql
initcdc.sql
EOF`

do
msg=""
mygrep $f $msg
done

執行輸出如下:
prvtjob.plb found in catproc.sql
dbmsaqds.plb found in catqueue.sql      catqueue.sql found in catproc.sql
prvtaqds.plb found in catqueue.sql      catqueue.sql found in catproc.sql
prvtlmd.plb found in catproc.sql
prvtlmc.plb found in catproc.sql
prvtbpp.plb found in catdpb.sql         catdpb.sql found in catproc.sql
prvtlsby.plb found in catproc.sql
prvtsum.plb found in catproc.sql
prvtsms.plb found in catproc.sql
dbmssum.sql found in catproc.sql
prvtdefr.plb found in catreps.sql       catreps.sql found in catrep.sql         catrep.sql found in catproc.sql
prvtbstr.plb found in catpstr.sql       catpstr.sql found in catproc.sql
prvtbcap.plb found in catpstr.sql       catpstr.sql found in catproc.sql
prvtaqiu.plb found in catqueue.sql      catqueue.sql found in catproc.sql
initqsma.sql found in catjava.sql
initcdc.sql found in catjava.sql

雖然存在遞迴呼叫,但最終都是在catproc.sql和catjava.sql指令碼里呼叫了,熟悉custome方式建庫的應該都知道這兩個指令碼在建庫階段必須呼叫的,
因此不需要執行catbundle.sql psu apply啦,神馬都是浮雲啦。

另外對於readme裡的view_recompile_jan2008cpu.sql也是不需要執行的,指令碼中的一小段:
CURSOR alter1(objectno number) IS
SELECT o.obj#,
'ALTER VIEW' || ' "' || u.name || '"."' || o.name || '" '
|| 'COMPILE '
FROM obj$ o, user$ u WHERE o.type#=4 AND
u.user# = o.owner# AND o.obj# in (select unique d_obj# from access$ where types=9)
AND o.obj# > objectno order by obj#;
該指令碼只是把所有符合條件的檢視COMPILE了一遍,這個在建庫的過程中都執行了

其實在readme裡也說了,需要run指令碼的只有以下幾種情況:
?Using DBCA (Database Configuration Assistant) to select a sample database (General, Data Warehouse, Transaction Processing)
?Using a script. that was created by DBCA that creates a database from a sample database
?Cloning a database that was created by either of the two preceding methods, and if Section 2.3.3.1, "Loading Modified .sql Files into the Database" and Section 2.3.3.2, "Recompiling Views in the Database" were not executed after PSU 10.2.0.4.2 was applied

對於view_recompile_jan2008cpu.sql則是:
Upgraded databases require that you perform. the steps in Section 2.3.3.2, "Recompiling Views in the Database" if these steps have not previously been performed; otherwise, no post-installation steps need to be performed.
即如果升級資料庫前沒有run過則需要跑一遍,如果以前曾經run過就不需要了,僅需一次而已。

當然如果你的庫是在安裝好PSU前就已經建立的了,則catbundle.sql psu apply必須run,view_recompile_jan2008cpu.sql則曾經run過就不需要了

另外有metalink賬戶的可以看下Introduction To Oracle Database catbundle.sql [ID 605795.1]這篇文章,其中有段:
Starting with Database 11.2.0.2.0, a dummy catbundle.sql is run at database upgrade and creation time, which creates a dba_registry_history entry with bundle series "PSU" and ID = "0". Reports that query on this view for the PSU series returns a row for every upgraded and newly created database.
即從11.2.0.2.0開始,建立一個新庫或者升級時會執行一個dummy catbundle.sql,這樣registry$history表中就有記錄了,也不會引起困惑了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25469263/viewspace-2641960/,如需轉載,請註明出處,否則將追究法律責任。

相關文章