一、背景介紹
某客戶資料庫備庫執行sql失敗,資料庫環境:主庫(12.2.0.1 RAC),備庫(12.2.0.1 單機)RAC到單機搭建了ADG,資料是從12.1.0.2通過erp導入的,報錯資訊:ORA-22303、ORA-16000、ORA-06508、ORA-06512,具體報錯内容見下文。
二、問題描述
1、執行SQL&報錯
2020-03-03 15:34:32.830 [job-81740957] INFO SingleTableSplitUtil - split pk [sql=SELECT * FROM ( SELECT xxx FROM xxx.xxx SAMPLE (0.1) WHERE (xxx IS NOT NULL) ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 15 ORDER by xxx ASC] is running...
2020-03-03 15:34:32.969 [job-81740957] ERROR JobContainer - Exception when job run
com.alibaba.datax.common.exception.DataXException: Code:[DBUtilErrorCode-07], Description:[讀取資料庫資料失敗. 請檢查您的配置的 column/table/where/querySql或者向 DBA 尋求幫助.]. - 執行的SQL為:SELECT * FROM ( SELECT xxx FROM xxx.xxx SAMPLE (0.1) WHERE (xxx IS NOT NULL) ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 15 ORDER by xxx ASC 具體錯誤資訊為:ORA-22303: 未找到類型 "SYS"."WRR$_REPLAY_DEP_GRAPH"
ORA-16000: 資料庫或可插入資料庫是以隻讀通路方式打開的
ORA-06508: PL/SQL: 無法找到正在調用 : "SYS.DBMS_WORKLOAD_REPLAY" 的程式單元
ORA-06512: 在 "SYS.DBMS_WRR_STATE", line 4
ORA-06512: 在 "SYS.DBMS_RANDOM", line 91
- java.sql.SQLException: ORA-22303: 未找到類型 "SYS"."WRR$_REPLAY_DEP_GRAPH"
ORA-16000: 資料庫或可插入資料庫是以隻讀通路方式打開的
ORA-06508: PL/SQL: 無法找到正在調用 : "SYS.DBMS_WORKLOAD_REPLAY" 的程式單元
ORA-06512: 在 "SYS.DBMS_WRR_STATE", line 4
ORA-06512: 在 "SYS.DBMS_RANDOM", line 91
三、問題排查
觀察上面報錯資訊,通過了解背景資訊,這個SQL在主庫RAC環境PDB通過業務使用者是可以查詢的,但是在備庫(單機)PDB環境執行卻報錯,通過下面幾個方面排查解決問題。
1、備庫查詢其他SQL
①備庫PDB業務業務使用者查詢其他sql能正常執行
②備庫執行上面SQL,不帶DBMS_RANDOM.VALUE可以正常執行
③主庫均能正常執行
2、備庫單獨調用DBMS_RANDOM.VALUE
通過上面一步,可以發現SQL執行報錯主要是在調用DBMS_RANDOM問題上,那麼接下來對備庫調用DBMS_RANDOM報錯進行分析。
2.1、sys連接配接到CDB、PDB
①sys使用者連接配接CDB,可以正常執行
②sys切換到對應PDB,執行報錯
sqlplus / as sysdba
alter session set container=pdb_name;
SQL> select DBMS_RANDOM.VALUE(1,8) from dual;
select DBMS_RANDOM.VALUE(1,8) from dual
*
ERROR at line 1:
ORA-22303: type "SYS"."WRR$_REPLAY_DEP_GRAPH" not found
ORA-16000: database or pluggable database open for read-only access
ORA-06508: PL/SQL: could not find program unit being called:"SYS.DBMS_WORKLOAD_REPLAY"
ORA-06512: at "SYS.DBMS_WRR_STATE", line 4
ORA-06512: at "SYS.DBMS_RANDOM", line 91
ORA-06512: at "SYS.DBMS_RANDOM", line 137
2.2、業務使用者連接配接到PDB模式
SQL執行報錯,報錯資訊和如下:
sqlplus user/[email protected]:1521/pwd-server-name
SQL> select DBMS_RANDOM.VALUE(1,8) from dual;
select DBMS_RANDOM.VALUE(1,8) from dual
*
ERROR at line 1:
ORA-22303: type "SYS"."WRR$_REPLAY_DEP_GRAPH" not found
ORA-16000: database or pluggable database open for read-only access
ORA-06508: PL/SQL: could not find program unit being called:"SYS.DBMS_WORKLOAD_REPLAY"
ORA-06512: at "SYS.DBMS_WRR_STATE", line 4
ORA-06512: at "SYS.DBMS_RANDOM", line 91
ORA-06512: at "SYS.DBMS_RANDOM", line 137
3、檢視資料庫INVALID對象
①主庫
SYS的Object對象全部valid,業務使用者有部分object invalid,對這次執行的SQL不影響。
②備庫
SYS的Object對象全部valid,業務使用者有部分object invalid,對這次執行的SQL不影響。
4、檢視使用者權限
在主、備庫查詢完使用者權限,主備是一緻的,資訊如下:
5、重新編譯DBMS_RANDOM包
主庫執行:
Execute the following script to recreate DBMS_RANDOM package:
@?/rdbms/admin/dbmsrand.sql
主庫執行完,這個動作會同步到從庫,執行完從庫在調用上述DBMS_RANDOM包,問題仍沒有解決
6、賦予業務使用者系統表權限
上面資訊觀察完仍沒有找到出錯原因,去查相關資料,發現類似報錯幾乎沒有,與報錯号相同的但是報錯内容是不一緻的,再次觀察報錯内容,嘗試賦予業務使用者系統表權限,如下:
主庫
sqlplus / as sysdba
alter session set container=pdb_name;
grant select on "SYS"."WRR$_REPLAY_DEP_GRAPH" to username;
權限賦予完,之後在備庫執行查詢指令,發現可以正常執行:
四、問題總結
遇到這個問題,查詢相關資料很少,最後根據sql執行報錯内容通過業務使用者查詢表 "SYS"."WRR$_REPLAY_DEP_GRAPH",發現沒有權限(主備庫查詢結果一緻),嘗試賦予這個使用者查詢這個系統表的權限,之後在執行上述查詢就可以了。
奇怪的一點,主庫業務使用者也是沒有這個系統表查詢權限的,但是執行sql可以正常執行,這也有可能觸發了oracle bug。