1. 程式人生 > 其它 >Oracle 12c PDB遷移及ORA-00600錯誤分析和解決(r10筆記第72天)

Oracle 12c PDB遷移及ORA-00600錯誤分析和解決(r10筆記第72天)

最近遷移一臺測試環境,準備整合到12c的PDB,常規的思路是用Datapump匯出匯入,對於資料較大的環境來說這個時間會比較長,為此自己也嘗試先升級這個測試庫,然後加入到CDB中去。

升級的過程就不多說了,其實對於大多數常規的業務來說,本身不是難點。

把升級後的NON-CDB加入到CDB中,基本是下面的思路,先把資料啟動到只讀模式,然後到處一個配置檔案,載入到CDB的重要地方就是使用這個配置檔案。先做檢查。

sqlplus / as sysdba
SQL> select name, CDB from v$database;
NAME      CDB
--------- ---
TESTDB    YES

SET SERVEROUTPUT ON
DECLARE
compatible CONSTANT VARCHAR2(3) :=
CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
pdb_descr_file => '/tmp/ncdb12c_actvdb.xml',
pdb_name => 'NCDB12C')
WHEN TRUE THEN 'YES'
ELSE 'NO'
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(compatible);
END;
/

NO
PL/SQL procedure successfully completed.

仔細一看這個地方竟然輸出了NO,對於這種情況需要檢視下面的資料字典來得到更多的資訊。

select name,cause,type,message,status from PDB_PLUG_IN_VIOLATIONS where name='NCDB12C';

比如會有下面的資訊:

NAME       CAUSE                          TYPE      MESSAGE                                            STATUS
---------- ------------------------------ --------- -------------------------------------------------- ---------
NCDB12C    Parameter                      WARNING   CDB parameter optimizer_index_caching mismatch:    PENDING
                                                    Previous 90 Current 0
NCDB12C    Parameter                      WARNING   CDB parameter pga_aggregate_target mismatch:       PENDING
                                                    Previous 788M Current 6440M
NCDB12C    SQL patch error                ERROR     (PSU bundle patch 160719 (Database Patch Set       PENDING
                                                    Update : 12.1.0.2.160719 (23054246)): APPLY
                                                    SUCCESS):  with status  in the PDB.

警告的資訊沒有大的影響,關鍵就在於ERROR

但是這個地方我就比較奇怪了,使用opatch lsinventory檢視,補丁是有的。而且其他的資料庫已經都部署多套了。這個為什麼就丟擲了這個問題呢。

為了儘快修復這個問題,我開啟生成的配置檔案,把SQL Patch的這一段資訊刪除了,然後再次執行上面的檢查指令碼就沒有問題了。

SQL> @a.sql

YES
PL/SQL procedure successfully completed.

基本的準備工作做完了,也算是有驚又險。

我們建立PDB,注意檔案路徑的對映。

SQL> CREATE PLUGGABLE DATABASE actvdb  using '/tmp/ncdb12c_actvdb.xml'
        copy file_name_convert=('/U01/app/oracle/oradata/actvdb','/home/U01/app/oracle/oradata/testdb/pdb/actvdb');
Pluggable database created.

這個過程時間會持續稍長一些,不過因為是在本地,所以影響不大,建立好之後,嘗試open這個PDB,發現不大對勁。

SQL> alter pluggable database actvdb open; Warning: PDB altered with errors.

檢查這個PDB的狀態,發現是受限的會話連線。

SQL> show pdbs;
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
      。。。
         8 ACTVDB                         READ WRITE YES

突然醒悟,還有一個重要的指令碼沒跑,那就是

@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

一遍感嘆粗心大意,一邊趕緊執行指令碼。

執行的過程中檢視PDB的狀態是MIGRATE

SQL> SQL> show pdbs
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
        。。。
         8 ACTVDB                         MIGRATE    YES

但是讓我有些意外的是這個指令碼執行失敗了,而且丟擲了ORA-00600的錯誤。

SQL> DECLARE
  2     threads pls_integer := &&1;
  3  BEGIN
  4     utl_recomp.recomp_parallel(threads);
  5  END;
  6  /
DECLARE
*
ERROR at line 1:
ORA-04045: errors during recompilation/revalidation of SYS.DBMS_QOPATCH
ORA-00600: internal error code, arguments: [kql_tab_diana:new dep],
[0x4C7382A68], [0x7F97536569A0], [1], [2], [], [], [], [], [], [], []
ORA-06512: at "SYS.DBMS_UTILITY", line 1294
ORA-06512: at line 1

因為也不大確定這個的影響範圍,檢視PDB的狀態,發現是受限的會話連線。

SQL> show pdbs;
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
        。。。
         8 ACTVDB                         READ WRITE YES

嘗試反覆啟停,還是同樣的錯誤,眼看升級遷移的時間越來越緊,儘管是測試環境,還是不能麻痺大意。

對於這個問題,真是讓我一頭霧水,檢視MOS也沒有找到直接的解答,而檢視OTN的問答,發現有些朋友也確實碰到了。有人找到了根上,那就是編譯一個包的時候會丟擲ORA-00600的錯誤。

我試了下,確實如此。

SQL> ALTER PACKAGE "SYS"."DBMS_QOPATCH" COMPILE BODY REUSE SETTINGS ;
ALTER PACKAGE "SYS"."DBMS_QOPATCH" COMPILE BODY REUSE SETTINGS
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kql_tab_diana:new dep],
[0x149CF37C0], [0x7F9BEA79DBD0], [1], [2], [], [], [], [], [], [], []

有些人嘗試重新建立編譯這個包,我在本地嘗試,發現還是丟擲了ORA-00600的錯誤。

SQL> @?/rdbms/admin/prvtqopi.plb
Session altered.
CREATE OR REPLACE PACKAGE BODY DBMS_QOPATCH wrapped
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [kql_tab_diana:new dep],
[0x149CF37C0], [0x7F9BEAB683B8], [1], [2], [], [], [], [], [], [], []

這個問題越發嚴峻,而我似乎只能找到一個有些相關的bug

Bug 20981713 : ORA-600 [KQL_TAB_DIANA:NEW DEP] DURING NONCDB_TO_PDB.SQL 過了一會兒之後,我再次嘗試停庫,然後重新啟動,發現竟然可以了。

當然我的內心是忐忑的,我深深知道很可能這個庫再停了之後就無法正常open了。

但是應用的連線能夠正常進來,也算是躲過了一劫,而馬上我就發現這個問題不是一般的糾結。因為我碰到了另外一個棘手的問題,那就是主庫雖然可以正常open了,忽略了裡面的警告,但是備庫的這個PDB卻偏偏無法正常open到read only狀態。

SQL> alter pluggable database all open;
alter pluggable database all open
*
ERROR at line 1:
ORA-01109: database not open

對於災備而言,這是極為嚴重,而且不合格的。但是問題的原因是什麼呢。

為了進一步實驗,我在備庫開啟了snapshot Standby,這樣備庫可讀可寫,就能夠模擬測試了,但是我發現問題是接二連三。

馬上發現這個PDB在open的時候報出了其它的ORA-00600錯誤。

Errors in file /home/U01/app/oracle/diag/rdbms/testdb2/testdb/trace/testdb_p005_24365.trc  (incident=140313) (PDBNAME=ACTVDB):
ORA-00600: internal error code, arguments: [kqlobjlod-no-result-from-proc$], [1403], [888], [], [], [], [], [], [], [], [], []
Incident details in: /home/U01/app/oracle/diag/rdbms/testdb2/testdb/incident/incdir_140313/testdb_p005_24365_i140313.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details. 

檢視MOS 找到了文章,但是還是沒有解決的方法。

ORA-600 [kqlobjlod-no-result-from-proc$] (Doc ID 1613402.1)

在查看了不少的文章之後,隱隱發現是在這個Patch上。

因為我在Snapshot Standby中測試了下面的命令,發現似乎容器的Patch沒有生效。

$  ./datapatch -verbose
....
Installing patches...
Patch installation complete.  Total patches installed: 7

所以在做了一個艱難的決定之後,我決定在主庫重新給這個PDB部署Patch,然後執行noncdb_to_pdb.sql

但是這樣做的風險就是這個PDB如果還是無法正常open,很可能的情況就是受限的會話連線,這樣的話我只能重新修復了,為此我花了些時間做了一個完整的邏輯備份,然後開始嘗試修復。

再次執行noncdb_to_pdb.sql的指令碼。

SQL> alter session set container=actvdb;
Session altered.
SQL> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

看到上次丟擲ORA-00600的地方會快就順利完成了,心裡總算鬆了口氣。然後嘗試open的時候發現這次丟擲了SQLPatch的Error

我在主庫端$ORACLE_HOME/OPatch下執行dbpach -verbose 短暫的等待之後,可以看到PDB已經部署了新的補丁。

Current state of SQL patches:
Bundle series PSU:
  ID 160719 in the binary registry and ID 160719 in PDB ACTVDB

然後重啟PDB,就恢復了正常。

SQL> alter session set container=actvdb;
Session altered.
SQL> shutdown immediate
Pluggable Database closed.
SQL> startup
Pluggable Database opened.
SQL> show pdbs;
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         8 ACTVDB                         READ WRITE NO

而這個問題在備庫就立竿見影,再次嘗試啟動備庫的PDB。

使用alter pluggable database all open就沒有問題了。

SQL> show pdbs;
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
        。。。
         8 ACTVDB                         READ ONLY  NO

SQL> select open_mode from v$database;
OPEN_MODE
--------------------
READ ONLY WITH APPLY   

這個問題總算告一段落,而對於SQL Patch也有了更深一層的理解。