Un exemple d'échec causé par les autorisations d'affichage du système en mode OceanBase Oracle

Lorsque les procédures stockées sont appelées sous les locataires Oracle et OB Oracle, les performances des deux sont incohérentes, ce qui entraîne un épissage incomplet du texte SQL obtenu, ce qui affecte les tests fonctionnels du côté métier. Cet article effectuera des tests et des vérifications pertinents sur ce problème.

Auteur : Zhao Liming, membre de l'équipe DBA MySQL d'Aikesheng. Il connaît les bases de données telles qu'Oracle et MySQL. Il est doué pour diagnostiquer les problèmes de performances des bases de données et analyser les problèmes de transaction et de verrouillage. Il est responsable de la gestion des opérations quotidiennes et maintenance du client MySQL et de la plate-forme DMP auto-développée par notre entreprise. Question, je suis très intéressé par les technologies liées aux bases de données open source.

Produit par la communauté open source Aikeson. Le contenu original ne peut être utilisé sans autorisation. Veuillez contacter l'éditeur et indiquer la source pour la réimpression.

Cet article compte environ 3 100 mots et sa lecture devrait prendre 10 minutes.

arrière-plan

Récemment, un client a rencontré un problème. Lorsque les procédures stockées étaient appelées sous les locataires Oracle et OB Oracle, les performances des deux étaient incohérentes, ce qui entraînait un épissage incomplet du texte SQL obtenu, ce qui affectait les tests fonctionnels du côté commercial.

La logique de la procédure stockée du client n'est pas compliquée : elle interroge simplement la vue système user_tab_columnspour obtenir le nom de la table de l'utilisateur, puis effectue un épissage SQL pour compléter la logique métier suivante.

Cet article effectuera des tests et des vérifications pertinents sur ce problème.

Récurrence du problème

Validation dans l'environnement Oracle

-- 创建测试用户并赋权
[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>

On peut voir que dans Oracle, qu'il s'agisse d'un utilisateur u1 ou u2, le nom de la table peut être renvoyé correctement lors de l'appel de la procédure stockée, indiquant que les résultats de retour user_tab_columnsdes deux vues de requête sont cohérents, ce qui est également conforme aux attentes.

Validation en environnement OB Oracle

-- 创建测试用户并赋权
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)

En fait, quelques indices peuvent être trouvés ici.Bien que les utilisateurs puissent être commutés via conn dans OB et que les utilisateurs commutés puissent également accéder à leurs propres objets, lors de l'accès à des vues telles que USER_, les résultats renvoyés sont différents de ceux d'Oracle.

Lorsque l'utilisateur u1 interroge user_tab_columnsla table, il ne peut voir que les tables sous l'utilisateur SYS (la table C a été créée par l'utilisateur SYS), donc la procédure stockée ne peut pas renvoyer le nom de la table T1 et le résultat de la requête est vide.

-- 直连 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)

Lorsque l'utilisateur u2 ne dispose pas de l'autorisation système SELECT ANY TABLE, même si all_tab_columnsla vue est interrogée, les informations sur les tables créées par d'autres utilisateurs ne peuvent pas être obtenues.

Dépanner les objets associés qui appellent les vues système

Objet PL

Objets PL, tels que fonctions, procédures stockées, 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;

afficher l'objet


-- 创建测试视图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_sourceLa colonne de texte dans la vue est de type varchar2 et vous pouvez directement utiliser like pour une requête floue.

  • dba_viewsLa colonne de texte dans la vue est de type long et vous ne pouvez pas utiliser directement like pour effectuer une requête floue, et une erreur ORA-00932 sera signalée.

Solution de contournement : créez d'abord une table, utilisez to_lobla fonction pour convertir le champ de texte en type clob, puis copiez dba_views dans la table, puis interrogez via le SQL ci-dessus.

-- 创建中间表并将系统视图 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

Cette méthode peut répondre aux besoins, mais chaque fois qu'une nouvelle vue est créée, la table doit être supprimée et reconstruite, ce qui est plus fastidieux.

Solution de contournement : créez des vues matérialisées pour remplacer les tables intermédiaires.

-- 创建物化视图
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_columnsBien que le remplacement de la vue dans la procédure stockée all_tab_columnspuisse être utilisé comme solution temporaire, il présente les inconvénients suivants :

  1. Le code métier doit être modifié, c'est-à-dire que la partie de la procédure stockée qui interroge les vues système pertinentes doit être remplacée.
  2. Les utilisateurs qui utilisent des synonymes pour accéder aux objets doivent disposer de l'autorisation système SELECT ANY TABLE, sinon l' all_objet cible ne pourra pas être interrogé même si la vue est utilisée.
  3. Accordez à l'utilisateur d'exécution l'autorité dba, modifiez la requête SQL d'origine et ajoutez la condition Owner='XXX' (il existe des risques de sécurité et ne sont pas recommandés).
  4. OB peut fournir un correctif pour résoudre complètement ce problème.

conclusion du problème

Dans OB, USER_TAB_COLUMNSla logique selon laquelle les utilisateurs ordinaires interrogent les autorisations d'affichage du système n'est pas cohérente avec Oracle, ce qui entraîne des différences dans les résultats des requêtes.

En plus des USER_TAB_COLUMNSvues, il existe d'autres USER_vues commençant par celles qui présentent également des problèmes similaires, telles que : USER_SYNONYMS, USER_TABLESetc.

Pour les objets existants dans le système, vous devez vérifier dès que possible et confirmer quels objets utilisent ces vues système. Avant que le problème ne soit complètement résolu, il est recommandé d'apporter des modifications temporaires au code concerné afin qu'il puisse continuer à compléter les fonctionnalités ultérieures. vérification.

Pour des articles plus techniques, veuillez visiter : https://opensource.actionsky.com/

À propos de SQLE

SQLE de la communauté open source Axon est un outil d'audit SQL destiné aux utilisateurs et gestionnaires de bases de données qui prend en charge les audits multi-scénarios, les processus en ligne standardisés, la prise en charge native des audits MySQL et les types de bases de données évolutives.

SQLE obtenir

taper adresse
Dépôt https://github.com/actiontech/sqle
document https://actiontech.github.io/sqle-docs/
publier des nouvelles https://github.com/actiontech/sqle/releases
Documentation de développement du plug-in d'audit des données https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Lei Jun : La version officielle du nouveau système d'exploitation de Xiaomi, ThePaper OS, a été packagée. La fenêtre pop-up sur la page de loterie de Gome App insulte son fondateur. Ubuntu 23.10 est officiellement publié. Autant profiter de vendredi pour mettre à jour ! Épisode de sortie d'Ubuntu 23.10 : L'image ISO a été "rappelée" de toute urgence en raison de la présence de discours de haine. Un doctorant de 23 ans a corrigé le "bug fantôme" de 22 ans dans Firefox. Le bureau à distance RustDesk 1.2.3 a été publié, Wayland amélioré pour prendre en charge la version TiDB 7.4 : compatible officiel avec MySQL 8.0. Après avoir débranché le récepteur USB Logitech, le noyau Linux s'est écrasé. Le maître a utilisé Scratch pour frotter le simulateur RISC-V et a exécuté avec succès le noyau Linux. JetBrains a lancé Writerside, un outil pour la création de documents techniques.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/actiontechoss/blog/10120128
conseillé
Classement