An example of failure caused by system view permissions in OceanBase Oracle mode

When the stored procedures are called under the Oracle and OB Oracle tenants, the performance of the two is inconsistent, resulting in incomplete splicing of the obtained SQL text, which affects the functional testing on the business side. This article will conduct relevant testing and verification on this issue.

Author: Zhao Liming, a member of the MySQL DBA team of Aikesheng. He is familiar with databases such as Oracle and MySQL. He is good at diagnosing database performance problems and analyzing transaction and lock problems. He is responsible for handling the daily operation and maintenance of customer MySQL and our company's self-developed DMP platform. Question, I am very interested in open source database related technologies.

Produced by the Aikeson open source community. Original content may not be used without authorization. Please contact the editor and indicate the source for reprinting.

This article is about 3100 words and is expected to take 10 minutes to read.

background

Recently, a customer encountered a fault. When the stored procedures were called under the Oracle and OB Oracle tenants, the performance of the two was inconsistent, resulting in incomplete splicing of the obtained SQL text, which affected the functional testing on the business side.

The customer's stored procedure logic is not complicated. It simply queries the system view user_tab_columnsto obtain the user's table name, and then performs SQL splicing to complete the subsequent business logic.

This article will conduct relevant testing and verification on this issue.

Problem recurrence

Validation in Oracle environment

-- 创建测试用户并赋权
[root@localhost ~]# sqlplus / as sysdba
SQL> create user u1 identified by u1;
User created.
SQL> create user u2 identified by u2;
User created.
SQL> grant connect,resource to u1;
Grant succeeded.
SQL> grant create procedure to u1;
Grant succeeded.
SQL> grant connect,resource to u2;
Grant succeeded.
SQL> grant create synonym to u2;
Grant succeeded.
SQL> grant select any table to u2;
Grant succeeded.

-- 创建测试表并赋权
SQL> conn u1/u1
Connected.
SQL> create table t1(id int);
Table created.
SQL> insert into t1(id) values(1);
1 row created.

-- 创建表的同义词
SQL> conn u2/u2
Connected.
SQL> create synonym t1 for u1.t1;
Synonym created.

SQL> set lin 200
SQL> col owner for a5
SQL> col table_owner for a5
SQL> col db_link for a10
SQL> select * from all_synonyms where owner='U2';

OWNER SYNONYM_NAME          TABLE TABLE_NAME           DB_LINK
----- ------------------------------ ----- ------------------------------ ----------
U2  T1               U1  T1

-- 创建存储过程并赋权
SQL> conn u1/u1
Connected.
SQL> create or replace procedure proc_case1 as
v_str varchar2(10);
begin
select table_name into v_str from user_tab_columns where table_name='T1';
dbms_output.put_line(v_str);
end;
/  2    3    4    5    6    7  

Procedure created.
SQL> grant execute on proc_case1 to u2;
Grant succeeded.

-- 创建存储过程同义词
SQL> conn u2/u2
Connected.
SQL> create synonym proc_case1 for u1.proc_case1;
Synonym created.

SQL> select * from all_synonyms where owner='U2';
OWNER SYNONYM_NAME                   TABLE TABLE_NAME                     DB_LINK
----- ------------------------------ ----- ------------------------------ ----------
U2    PROC_CASE1                     U1    PROC_CASE1
U2    T1                             U1    T1

-- 验证
SQL> conn u1/u1
Connected.
SQL> select * from t1;
        ID
----------
         1

SQL> set serveroutput on;
SQL> call proc_case1();
T1
Call completed.

SQL> conn u2/u2
Connected.
SQL> select * from t1;
        ID
----------
         1

SQL> set serveroutput on;
SQL> call proc_case1();
T1
Call completed.
SQL>

It can be seen that in Oracle, whether it is u1 or u2 user, the table name can be returned correctly when calling the stored procedure, indicating that the user_tab_columnsreturn results of the two query views are consistent, which is also in line with expectations.

Validation in OB Oracle environment

-- 创建测试用户并赋权
SYS[SYS]> create user u1 identified by u1;
Query OK, 0 rows affected (0.04 sec)
SYS[SYS]> create user u2 identified by u2;
Query OK, 0 rows affected (0.04 sec)
SYS[SYS]> grant connect,resource to u1;
Query OK, 0 rows affected (0.04 sec)
SYS[SYS]> grant create procedure to u1;
Query OK, 0 rows affected (0.03 sec)
SYS[SYS]> grant connect,resource to u2;
Query OK, 0 rows affected (0.05 sec)
SYS[SYS]> grant create synonym to u2;
Query OK, 0 rows affected (0.03 sec)
SYS[SYS]> grant select any table to u2;
Query OK, 0 rows affected (0.03 sec)

-- 创建测试表并赋权
SYS[SYS]> conn u1
Connection id:  269006
Current database: U1
SYS[U1]> create table t1(id int);
Query OK, 0 rows affected (0.21 sec)
SYS[U1]> insert into t1(id) values(1);
Query OK, 1 row affected (0.03 sec)
SYS[U1]> commit;
Query OK, 0 rows affected (0.01 sec)

-- 创建表的同义词
SYS[U1]> conn u2
Connection id:  50837
Current database: U2
SYS[U2]> create synonym t1 for u1.t1;
Query OK, 0 rows affected (0.05 sec)
SYS[U2]> select * from all_synonyms where owner='U2';
+-------+--------------+-------------+------------+---------+
| OWNER | SYNONYM_NAME | TABLE_OWNER | TABLE_NAME | DB_LINK |
+-------+--------------+-------------+------------+---------+
| U2    | T1           | U1          | T1         | NULL    |
+-------+--------------+-------------+------------+---------+
2 rows in set (0.01 sec)

-- 创建存储过程并赋权
SYS[U2]> conn u1
Connection id:  269078
Current database: U1
SYS[U1]> create or replace procedure proc_case1 as
  -> v_str varchar2(10);
  -> begin
  -> select table_name into v_str from user_tab_columns where table_name='T1';
  -> dbms_output.put_line(v_str);
  -> end;
  -> /
Query OK, 0 rows affected (0.17 sec)
SYS[U1]> grant execute on proc_case1 to u2;
Query OK, 0 rows affected (0.06 sec)

-- 创建存储过程同义词
SYS[U1]> conn u2
Connection id:  50896
Current database: U2
SYS[U2]> create synonym proc_case1 for u1.proc_case1;
Query OK, 0 rows affected (0.05 sec)
SYS[U2]> select * from all_synonyms where owner='U2';
+-------+--------------+-------------+------------+---------+
| OWNER | SYNONYM_NAME | TABLE_OWNER | TABLE_NAME | DB_LINK |
+-------+--------------+-------------+------------+---------+
| U2    | PROC_CASE1   | U1          | PROC_CASE1 | NULL    |
| U2    | T1           | U1          | T1         | NULL    |
+-------+--------------+-------------+------------+---------+
2 rows in set (0.01 sec)

-- 验证
SYS[U2]> conn u1
Connection id:  269134
Current database: U1
SYS[U1]> select * from t1;
+------+
| ID   |
+------+
|    1 |
+------+
1 row in set (0.01sec)

SYS[U1]> set serveroutput on;
Query OK, 0 rows affected (0.41 sec)
SYS[U1]> call proc_case1();
Query OK, 0 rows affected (0.21 sec)
SYS[U1]> select table_name,column_name from user_tab_columns;
+------------+-------------+
| TABLE_NAME | COLUMN_NAME |
+------------+-------------+
| C          | NAME        |
| C          | ADDRESS     |
+------------+-------------+
2 rows in set (0.08 sec)

In fact, some clues can be found here. Although users can be switched through conn in OB, and the switched users can also access their own objects, when accessing views such as USER_, the returned results are different from Oracle.

When user u1 queries user_tab_columnsthe table, he can only see the tables under the SYS user (table C was created by the SYS user), so the stored procedure cannot return the table name of the T1 table, and the query result is empty.

-- 直连 u1 用户验证
U1[U1]> select * from t1;
+------+
| ID   |
+------+
|    1 |
+------+
1 row in set (0.01sec)

U1[U1]> set serveroutput on;
Query OK, 0 rows affected (0.02sec)

U1[U1]> call proc_case1();
Query OK, 0 rows affected (0.08sec)

T1
U1[U1]>

-- 直连 u2 用户进行验证
U2[U2]> select * from t1;
+------+
| ID   |
+------+
|    1 |
+------+
1 row in set (0.03sec)

U2[U2]> set serveroutput on;
Query OK, 0 rows affected (0.44 sec)

U2[U2]> call proc_case1();
Query OK, 0 rows affected (0.43 sec)

U2[U2]> select * from user_tab_columns;
Empty set (0.08 sec)

# 同样地,u2 也无法从 user_tab_columns 视图中查询到 u1 创建的表,调用存储过程返回结果为空

-- 将 user_tab_columns 替换成 all_tab_columns 视图
U2[U2]> select table_name,column_name from all_tab_columns where owner='U1';
+------------+-------------+
| TABLE_NAME | COLUMN_NAME |
+------------+-------------+
| T1         | ID          |
+------------+-------------+
1 row in set (0.08 sec)

U2[U2]> create or replace procedure proc_case2 as
    -> v_str varchar2(10);
    -> begin
    -> select table_name into v_str from all_tab_columns where table_name='T1' and owner='U1';
    -> dbms_output.put_line(v_str);
    -> end;
    -> /
Query OK, 0 rows affected (0.17ec)

U2[U2]> call proc_case2();
Query OK, 0 rows affected (0.16ec)

T1
U2[U2]>

-- 将 SELECT ANY TABLE 权限回收
SYS[SYS]> revoke select any table from u2;
Query OK, 0 rows affected (0.03 sec)

U2[U2]> select table_name,column_name from all_tab_columns where owner='U1';
Empty set (0.05 sec)

U2[U2]> set serveroutput on;
Query OK, 0 rows affected (0.01 sec)

U2[U2]> call proc_case2();
Query OK, 0 rows affected (0.05 sec)

When user u2 does not have the SELECT ANY TABLE system permission, even if all_tab_columnsthe view is queried, information about tables created by other users cannot be obtained.

Troubleshoot related objects that call system views

PL object

PL objects, such as functions, stored procedures, etc.


-- dba_source 视图中存放了各种 PL 对象的定义
SQL> select count(*),type from dba_source group by type;

 COUNT(*) TYPE
---------- ------------
  152202 PROCEDURE
   89318 PACKAGE
   31504 PACKAGE BODY
   1276 TYPE BODY
   2210 TRIGGER
   3895 FUNCTION
     7 JAVA SOURCE
   12338 TYPE

8 rows selected.

-- 创建测试存储过程(大小写各1个)

SQL> CREATE OR REPLACE PROCEDURE PROC_1 IS
V_N NUMBER :=0;
BEGIN
 SELECT COUNT(*) INTO V_N FROM USER_TAB_COLUMNS;
END;
/ 2  3  4  5  6 

Procedure created.

SQL> create or replace procedure proc_2 is
v_n number :=0;
begin
 select count(*) into v_n from user_tab_columns;
end;
/ 2  3  4  5  6 

Procedure created.

-- 查询常用系统视图名(此处只列举了几个与表相关的视图)
select owner,object_name,object_type from dba_objects where owner='SYS' and (object_name like 'USER_PART_%' or object_name like 'USER_T%' or object_name like 'ALL_PART_%' or object_name like 'ALL_T%' or object_name like 'DBA_PART_%' or object_name like 'DBA_T%');

-- 根据上一步获取到的系统视图名,通过模糊搜索,即可捕获到涉及查询这些系统视图的 PL 对象
SQL> set line 200 pages 9999 long 999999
SQL> col owner for a10
SQL> col name for a30
SQL> col text for a80
SQL> select owner,name,type,text from dba_source where owner not in('SYS', 'SYSTEM', 'SYSMAN', 'OUTLN', 'DIP', 'TSMSYS', 'DBSNMP',
     'ORACLE_OCM', 'WMSYS', 'EXFSYS', 'XDB', 'ANONYMOUS', 'ORDSYS',
     'ORDPLUGINS', 'SI_INFORMTN_SCHEMA', 'MDSYS', 'MGMT_VIEW', 'PERFSTAT',
     'DMSYS', 'CTXSYS', 'OLAPSYS', 'MDDATA', 'APPQOSSYS', 'XS$NULL',
     'ORDDATA', 'SPATIAL_WFS_ADMIN_USR', 'SPATIAL_CSW_ADMIN_USR',
     'OWBSYS', 'APEX_PUBLIC_USER', 'APEX_030200', 'FLOWS_FILES', 'SCOTT',
     'OMS', 'OWBSYS_AUDIT', 'DSG', 'DBMGR', 'PATROL', 'SPA', 'GOLDENGATE',
     'DBADM') and owner not like 'MYNET%' and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%'); 2  3  4  5  6  7  8 

OWNER   NAME              TYPE     TEXT
---------- ------------------------------ ------------ --------------------------------------------------------------------------------

U1     PROC_CASE1           PROCEDURE  select table_name into v_str from user_tab_columns where table_name='T1';
ZLM    PROC_1             PROCEDURE   SELECT COUNT(*) INTO V_N FROM USER_TAB_COLUMNS;
ZLM    PROC_2             PROCEDURE   select count(*) into v_n from user_tab_columns;

view object


-- 创建测试视图1
SQL> create view view_1 as select * from user_tables;
View created.

-- 查询 dba_views 获取视图定义
SQL> select owner,view_name,text from dba_views where owner not in('SYS', 'SYSTEM', 'SYSMAN', 'OUTLN', 'DIP', 'TSMSYS', 'DBSNMP',
     'ORACLE_OCM', 'WMSYS', 'EXFSYS', 'XDB', 'ANONYMOUS', 'ORDSYS',
     'ORDPLUGINS', 'SI_INFORMTN_SCHEMA', 'MDSYS', 'MGMT_VIEW', 'PERFSTAT',
     'DMSYS', 'CTXSYS', 'OLAPSYS', 'MDDATA', 'APPQOSSYS', 'XS$NULL',
     'ORDDATA', 'SPATIAL_WFS_ADMIN_USR', 'SPATIAL_CSW_ADMIN_USR',
     'OWBSYS', 'APEX_PUBLIC_USER', 'APEX_030200', 'FLOWS_FILES', 'SCOTT',
     'OMS', 'OWBSYS_AUDIT', 'DSG', 'DBMGR', 'PATROL', 'SPA', 'GOLDENGATE',
     'DBADM') and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%');
 2  3  4  5  6  7  8     'DBADM') and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%')
                                                                                                                          *
ERROR at line 8:

ORA-00932: inconsistent datatypes: expected NUMBER got LONG

  • dba_sourceThe text column in the view is of varchar2 type, and you can directly use like for fuzzy query.

  • dba_viewsThe text column in the view is of long type, and you cannot directly use like to perform fuzzy query, and an ORA-00932 error will be reported.

Workaround: First create a table, use to_lobthe function to convert the text field to clob type, then copy dba_views to the table, and then query through the above SQL.

-- 创建中间表并将系统视图 dba_views 内容拷贝到该表
SQL> create table my_views as select owner,view_name,to_lob(text) text from dba_views;

Table created.

-- 查询中间表捕获目标视图对象
SQL> select owner,view_name,text from my_views where owner not in('SYS', 'SYSTEM', 'SYSMAN', 'OUTLN', 'DIP', 'TSMSYS', 'DBSNMP',     'ORACLE_OCM', 'WMSYS', 'EXFSYS', 'XDB', 'ANONYMOUS', 'ORDSYS',     'ORDPLUGINS', 'SI_INFORMTN_SCHEMA', 'MDSYS', 'MGMT_VIEW', 'PERFSTAT',     'DMSYS', 'CTXSYS', 'OLAPSYS', 'MDDATA', 'APPQOSSYS', 'XS$NULL',     'ORDDATA', 'SPATIAL_WFS_ADMIN_USR', 'SPATIAL_CSW_ADMIN_USR',     'OWBSYS', 'APEX_PUBLIC_USER', 'APEX_030200', 'FLOWS_FILES', 'SCOTT',     'OMS', 'OWBSYS_AUDIT', 'DSG', 'DBMGR', 'PATROL', 'SPA', 'GOLDENGATE',     'DBADM') and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%'); 2  3  4  5  6  7  8 
OWNER   VIEW_NAME           TEXT---------- ------------------------------ --------------------------------------------------------------------------------
ZLM    VIEW_1             select "TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FR                     EE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTEN                     TS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED                     _UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","A                     VG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TA                     BLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SE                     CONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURA                     TION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","                     DROPPED" from user_tables

This method can meet the needs, but every time a new view is created, the table needs to be dropped and rebuilt, which is more cumbersome.

workaround: Create materialized views to replace intermediate tables.

-- 创建物化视图
SQL> create materialized view my_mviews 
refresh force 
on demand 
start with sysdate
next sysdate + 10 /(24*60)
as 
select owner,view_name,to_lob(text) text from dba_views; 2  3  4  5  6  7 

Materialized view created.

-- 创建测试视图2
SQL> CREATE VIEW VIEW_2 AS SELECT * FROM USER_TABLES;
View created.

-- 查看是否捕获到 view_2 视图
SQL> select owner,view_name,text from my_mviews where owner not in('SYS', 'SYSTEM', 'SYSMAN', 'OUTLN', 'DIP', 'TSMSYS', 'DBSNMP',
     'ORACLE_OCM', 'WMSYS', 'EXFSYS', 'XDB', 'ANONYMOUS', 'ORDSYS',
     'ORDPLUGINS', 'SI_INFORMTN_SCHEMA', 'MDSYS', 'MGMT_VIEW', 'PERFSTAT',
     'DMSYS', 'CTXSYS', 'OLAPSYS', 'MDDATA', 'APPQOSSYS', 'XS$NULL',
     'ORDDATA', 'SPATIAL_WFS_ADMIN_USR', 'SPATIAL_CSW_ADMIN_USR',
     'OWBSYS', 'APEX_PUBLIC_USER', 'APEX_030200', 'FLOWS_FILES', 'SCOTT',
     'OMS', 'OWBSYS_AUDIT', 'DSG', 'DBMGR', 'PATROL', 'SPA', 'GOLDENGATE',
     'DBADM') and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%'); 2  3  4  5  6  7  8 

OWNER   VIEW_NAME           TEXT
---------- ------------------------------ --------------------------------------------------------------------------------
ZLM    VIEW_1             select "TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FR
                     EE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTEN
                     TS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED
                     _UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","A
                     VG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TA
                     BLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SE
                     CONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURA
                     TION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","
                     DROPPED" from user_tables

-- 查看物化视图刷新时间  
SQL> select owner,mview_name,last_refresh_type,last_refresh_date from user_mviews;
OWNER   MVIEW_NAME           LAST_REF LAST_REFRESH_DATE
---------- ------------------------------ -------- -------------------
ZLM    MY_MVIEWS           COMPLETE 2023-08-03 16:07:15

-- 手动刷新物化视图
SQL> exec dbms_mview.refresh('my_mviews');

PL/SQL procedure successfully completed.

SQL> select owner,mview_name,last_refresh_type,last_refresh_date from user_mviews;

OWNER   MVIEW_NAME           LAST_REF LAST_REFRESH_DATE
---------- ------------------------------ -------- -------------------
ZLM    MY_MVIEWS           COMPLETE 2023-08-03 16:21:45

-- 再次查询物化视图,此时 view_2 也能被捕获到了,这样就无需重复建表,当有新视图被创建的时候,只需手动刷新物化视图即可
SQL> select owner,view_name,text from my_mviews where owner not in('SYS', 'SYSTEM', 'SYSMAN', 'OUTLN', 'DIP', 'TSMSYS', 'DBSNMP',
     'ORACLE_OCM', 'WMSYS', 'EXFSYS', 'XDB', 'ANONYMOUS', 'ORDSYS',
     'ORDPLUGINS', 'SI_INFORMTN_SCHEMA', 'MDSYS', 'MGMT_VIEW', 'PERFSTAT',
     'DMSYS', 'CTXSYS', 'OLAPSYS', 'MDDATA', 'APPQOSSYS', 'XS$NULL',
     'ORDDATA', 'SPATIAL_WFS_ADMIN_USR', 'SPATIAL_CSW_ADMIN_USR',
     'OWBSYS', 'APEX_PUBLIC_USER', 'APEX_030200', 'FLOWS_FILES', 'SCOTT',
     'OMS', 'OWBSYS_AUDIT', 'DSG', 'DBMGR', 'PATROL', 'SPA', 'GOLDENGATE',
     'DBADM') and (text like '%USER_TAB_COLUMNS%' or text like '%user_tab_columns%' or text like '%USER%TABLES%' or text like '%user%tables%' or text like '%ALL_TAB_COLUMNS%' or text like '%ALL_tab_columns%' or text like '%ALL%TABLES%' or text like '%ALL%tables%'); 2  3  4  5  6  7  8 

OWNER   VIEW_NAME           TEXT
---------- ------------------------------ --------------------------------------------------------------------------------
ZLM    VIEW_1             select "TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FR
                     EE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTEN
                     TS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED
                     _UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","A
                     VG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TA
                     BLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SE
                     CONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURA
                     TION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","
                     DROPPED" from user_tables

ZLM    VIEW_2             select "TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FR
                     EE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTEN
                     TS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED
                     _UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","A
                     VG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TA
                     BLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SE
                     CONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURA
                     TION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","
                     DROPPED" from USER_TABLES

solution

user_tab_columnsAlthough replacing the view in the stored procedure all_tab_columnscan be used as a temporary solution, it has the following disadvantages:

  1. The business code needs to be modified, that is, the part of the stored procedure that queries the relevant system views needs to be replaced.
  2. Users who use synonyms to access objects need to have the SELECT ANY TABLE system permission. Otherwise, the all_target object cannot be queried even if the view is used.
  3. Grant the execution user dba authority, modify the original query SQL, and add the condition owner='XXX' (there are security risks and are not recommended).
  4. OB can provide a hotfix patch to completely solve this problem.

conclusion of issue

In OB, USER_TAB_COLUMNSthe logic of ordinary users querying system view permissions is not consistent with Oracle, resulting in differences in query results.

In addition to USER_TAB_COLUMNSviews, there are other USER_views starting with which also have similar problems, such as: USER_SYNONYMS, USER_TABLESetc.

For existing objects in the system, you should check as soon as possible and confirm which objects use these system views. Before the problem is completely fixed, it is recommended to make temporary modifications to the relevant code so that it can continue to complete subsequent functional verification.

For more technical articles, please visit: https://opensource.actionsky.com/

About SQLE

SQLE from the Axon open source community is a SQL audit tool for database users and managers that supports multi-scenario audits, standardized online processes, native support for MySQL audits and scalable database types.

SQLE get

type address
Repository https://github.com/actiontech/sqle
document https://actiontech.github.io/sqle-docs/
release news https://github.com/actiontech/sqle/releases
Data audit plug-in development documentation https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Lei Jun: The official version of Xiaomi's new operating system ThePaper OS has been packaged. The pop-up window on the lottery page of Gome App insults its founder. Ubuntu 23.10 is officially released. You might as well take advantage of Friday to upgrade! Ubuntu 23.10 release episode: The ISO image was urgently "recalled" due to containing hate speech. A 23-year-old PhD student fixed the 22-year-old "ghost bug" in Firefox. RustDesk remote desktop 1.2.3 was released, enhanced Wayland to support TiDB 7.4 Release: Official Compatible with MySQL 8.0. After unplugging the Logitech USB receiver, the Linux kernel crashed. The master used Scratch to rub the RISC-V simulator and successfully ran the Linux kernel. JetBrains launched Writerside, a tool for creating technical documents.
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/actiontechoss/blog/10120128